package services.common;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import models.common.bean.UserCreditDebtLeaderBean;
import models.common.entity.t_company_info_side;
import models.common.entity.t_creditor_right_debt;
import models.common.entity.t_user_credit;
import models.common.entity.t_user_credit_detail;
import models.common.entity.t_user_credit.AuditResult;
import services.base.BaseService;

import common.enums.NoticeScene;
import common.enums.ServiceType;
import common.utils.Factory;
import common.utils.LoggerUtil;
import common.utils.OrderNoUtil;
import common.utils.PageBean;
import common.utils.ResultInfo;

import daos.common.UserCreditDao;

/**
 * 信用额度申请service
 * 
 * @author fanghanyong
 * @version 2018-01-11 上午11:00:00
 */
public class UserCreditService extends BaseService<t_user_credit> {

	protected UserCreditDao userCreditDao = Factory.getDao(UserCreditDao.class);
	
	protected CreditorRightDebtService creditorRightDebtService = Factory.getService(CreditorRightDebtService.class);
	
	protected NoticeService noticeService = Factory.getService(NoticeService.class);
	
	protected CompanyInfoSideService companyInfoSideService = Factory.getService(CompanyInfoSideService.class);
	
	protected UserCreditDetailService userCreditDetailService = Factory.getService(UserCreditDetailService.class);
	

	public UserCreditService() {
		userCreditDao = Factory.getDao(UserCreditDao.class);
		super.basedao = this.userCreditDao;
	}

	/**
	 * 更新数据
	 * 
	 * @param t
	 * @return
	 * @author fanghanyong
	 * @version 2018-01-11
	 */
	public boolean save(t_user_credit t) {
		return userCreditDao.save(t);
	}

	/**
	 * 更新授信额度的审核状态
	 * 
	 * @param id
	 * @param status
	 * @return
	 * @author fanghanyong
	 * @createDate 2018年01月11日
	 * 
	 */
	public int updateById(long id, int status) {

		return userCreditDao.updateById(id, status);
	}


	/**
	 * 后台 -- 分页查询 查询放款人对应的申请列表
	 * 
	 * @param currPage
	 * @param pageSize
	 * @param userId
	 * @param leaderName
	 *            放款人名称
	 * @param startDate
	 *            授信时间
	 * @param endDate
	 *            授信终止时间
	 * @param showType
	 *            额度状态
	 * @return
	 * 
	 * @author fanghanyong
	 * @createDate 2018年01月11日
	 * 
	 */
	public PageBean<t_user_credit> pageOfUserCredit(int currPage, int pageSize,
			long userId, String leaderName, String startDate, String endDate, int showType,int exports) {

		return userCreditDao.pageOfUserCredit(currPage, pageSize, userId,
				leaderName, startDate, endDate, showType, exports);
	}


	/**
	 * 根据申请用户ID 和放款人 id 查询 授信额度
	 * 
	 * @param user_id
	 *            申请人id
	 * @param lender_id
	 *            放款人id
	 * @return
	 * @author xiaojun
	 * @version 2018-1-12
	 */
	public t_user_credit findByUserId(long user_id, long lender_id) {
		return findByColumn(" user_id = ? AND lender_id = ? AND status = 0 and parent_id=0 ", user_id,lender_id);
	}
	/**
	 * 根据申请用户ID 和 父级id  查询 授信额度
	 * 
	 * @param user_id 申请人id 
	 * @param parent_id 父级id
	 * @return
	 * @author xiaojun
	 * @version 2018-1-12
	 */
	public t_user_credit findByUserTransfer(long user_id, long parent_id, String credit_granting_code) {
		return findByColumn(" user_id = ? AND parent_id = ?  and credit_granting_code like ? ", user_id,parent_id,credit_granting_code+"-"+"_");
	}
	/**
	 * 获取流转授信id
	 *
	 * @param code
	 * @return
	 * @author xiaojun
	 *@version 2018-2-1
	 */
	public String getGrantingCcode(String code){
		t_user_credit user_credit = null;
		String orgiCode = code;
		for (int i = 1; i>0; i++) {
			code = code+"-"+i;
			user_credit = findByColumn(" credit_granting_code = ?", code);
			if(user_credit == null){
				return code;
			}else{
				code=orgiCode;
			}
		}
		return code+"*1";
	}
	/**
	 * 分页查询 查询放款人对应的申请列表
	 * 
	 * @param currPage
	 * @param pageSize
	 * @param lenderId
	 * @return
	 * 
	 * @author fanghanyong
	 * @createDate 2018年01月11日
	 * 
	 */
	public PageBean<t_user_credit> pageOfUserCreditByLenderId(int currPage,
			int pageSize, long lenderId) {

		return userCreditDao.pageOfUserCreditByLenderId(currPage, pageSize,
				lenderId);
	}

	/**
	 * 
	 * 修改状态
	 * 
	 * @param status
	 * @param olStatus
	 * @param id
	 * @return
	 * @author xiaojun
	 * @version 2018-1-16
	 */
	public boolean updateLimit(t_user_credit user_credit) {
		StringBuffer updSql = new StringBuffer(
				"UPDATE t_user_credit SET usable_limit = :usable_limit,transfer_used_limit = :transfer_used_limit,transferee_limit = :transferee_limit WHERE id=:id  ");
		Map<String, Object> params = new HashMap<String, Object>();
		params.put("usable_limit", user_credit.usable_limit);
		params.put("transfer_used_limit", user_credit.transfer_used_limit);
		params.put("transferee_limit", user_credit.transferee_limit);
		params.put("id", user_credit.id);

		return userCreditDao.updateBySQL(updSql.toString(), params) == 1 ? true
				: false;
	}


	/**
	 * 分页查询 放款人-用户授信额度信息总金额
	 * 
	 * @param currPage
	 * @param pageSize
	 * @param lender_id
	 *            放款人ID
	 * @param endDate
	 *            授信终止时间
	 * @param showType
	 *            额度状态
	 * @return
	 * @author fanghanyong
	 * @createDate 2018年01月11日
	 */
	public Map<String, Object> findMapBySQLByLeaderId(int currPage,
			int pageSize, long lender_id, String applyName, String startDate,
			String endDate, int showType) {

		return userCreditDao.findMapBySQLByLeaderId(currPage, pageSize,
				lender_id, applyName, startDate, endDate, showType);
	}

	/**
	 * 分页查询 用户授信额度
	 * 
	 * @param currPage
	 * @param pageSize
	 * @param lender_id
	 *            放款人ID
	 * @param applyName
	 *            融通人名称
	 * @param startDate
	 *            授信起始时间
	 * @param endDate
	 *            授信终止时间
	 * @param showType
	 *            额度状态
	 * @return
	 * @author fanghanyong
	 * @createDate 2018年01月22日
	 */
	public PageBean<UserCreditDebtLeaderBean> pageOfUserCreditByleaId(
			int currPage, int pageSize, long lender_id, String applyName,
			String startDate, String endDate, int showType, int exports) {

		return userCreditDao.pageOfUserCreditByleaId(currPage, pageSize,
				lender_id, applyName, startDate, endDate, showType, exports);
	}

	/**
	 * 还额度
	 * 
	 * @param userId
	 *            授信额度的id
	 * @param amount
	 *            对应的额度
	 * @return
	 * @author liaijun
	 * @version 2018年1月23日
	 */
	public int updateToUser(long id, double amount) {
		return userCreditDao.updateToUser(id, amount);
	}

	/**
	 * 使用额度
	 * 
	 * @param userId
	 *            当前融通人用户的id
	 * @param amount
	 *            对应的额度
	 * @return
	 * @author liaijun
	 * @version 2018年1月23日
	 */
	public int updateaddToUser(long userId, double amount) {
		return userCreditDao.updateaddToUser(userId, amount);
	}

	/**
	 * 后台---分页查询 用户授信额度
	 * 
	 * @param currPage
	 * @param pageSize
	 * @param creditId
	 *            授信申请id
	 * @param applyName
	 *            融通人名称
	 * @param leanderName
	 *            放款人名称
	 * @param showType
	 *            授信使用状态
	 * @return
	 * @author fanghanyong
	 * @createDate 2018年01月22日
	 */
	public PageBean<t_user_credit> pageOfUserCredit(int currPage, int pageSize,
			String applyName, String leanderName, long creditId, int showType,int orderValue,int exports) {

		return userCreditDao.pageOfUserCredit(currPage, pageSize,applyName,
				leanderName, creditId, showType,orderValue,exports);
	}

	/**
	 * 分页查询 用户授信额度-总额度
	 * 
	 * @param creditId
	 *            授信申请id
	 * @param applyName
	 *            融通人名称
	 * @param leanderName
	 *            放款人名称
	 * @return
	 * @author fanghanyong
	 * @createDate 2018年01月22日
	 */
	public Map<String, Object> totalUserCredit(String applyName,
			String leanderName, long creditId) {

		return userCreditDao.totalUserCredit(applyName, leanderName, creditId);
	}
	/**
	 * 标记额度到期
	 *
	 * @return
	 * @author xiaojun
	 *@version 2018-1-30
	 */
	public ResultInfo creditMarkOverdueJob(){
		return userCreditDao.creditMarkOverdueJob();
	}

	/**
	 *	根据授信id更改其状态（收到的数字账款凭证-确认收票）
	 * @param credit_granting_code
	 * @param status
	 * @return
	 * @author Liangqiongfeng
	 *@version 2018-3-10 
	 */
	public boolean updateStatusById(Long id, double digital_com_paper_money) {
		// TODO Auto-generated method stub
		return userCreditDao.updateStatusById(id, digital_com_paper_money);
	}

	/**
	 * 根据绑定的应付账款，把当前授信授予应付账款的债权人
	 * @return
	 * @author Liangqiongfeng
	 *@version 2018-3-22 
	 * @param userCredit 当前授信申请的数据
	 * @param creditorRightDebt 绑定当前授信申请的应付账款
	 */
	/*public ResultInfo toApply(t_creditor_right_debt creditorRightDebt, t_user_credit oluserCredit) {
		
		ResultInfo result = new ResultInfo();
		
		//根据授信申请绑定的应付账款，给应付账款债权人 增加受让额度
		t_user_credit userCredit = findByUserTransfer(
				creditorRightDebt.company_id, oluserCredit.id, oluserCredit.credit_granting_code);
		
		if (userCredit == null) {
			userCredit = new t_user_credit();
			userCredit.time = new Date();
			userCredit.setStatus(AuditResult.TRANSFER);
			userCredit.user_id = creditorRightDebt.company_id;
			userCredit.user_name = creditorRightDebt.creditor_name;
			userCredit.credit_granting_code =getGrantingCcode(oluserCredit.credit_granting_code);
			userCredit.start_time = oluserCredit.start_time;
			userCredit.end_time = oluserCredit.end_time;
			userCredit.financing_confine_limit = oluserCredit.financing_confine_limit;
			userCredit.bond_percent = oluserCredit.bond_percent;
			userCredit.custodian_fee = oluserCredit.custodian_fee;
			userCredit.flow_limit = oluserCredit.flow_limit;
			userCredit.parent_id = oluserCredit.id;
			userCredit.lender_id = oluserCredit.lender_id;
			userCredit.lender_name = oluserCredit.lender_name;
			
		}
		//如果应付账款已经进行过转开，不允许绑定授信申请
		if(creditorRightDebt.creditor_money != creditorRightDebt.rest_debt_money ){
			LoggerUtil.error(false, "当前账款信息不可绑定授信申请");
			result.code = -1;
			result.msg = "当前账款信息不可绑定授信申请";
			return result;
		}
		
		double account = 0.0;
		
		//如果应付账款额度大于上一级可用授信额度
		if(creditorRightDebt.creditor_money >= oluserCredit.usable_limit){
			userCredit.transferee_limit += oluserCredit.usable_limit;
			userCredit.transferee_used_limit += oluserCredit.usable_limit;
			userCredit.usable_limit += oluserCredit.usable_limit;
			
			//增加可质押金额
			userCredit.pledged_limit += oluserCredit.usable_limit;
			
			//TODO
			account = oluserCredit.usable_limit;
			
			creditorRightDebt.rest_debt_money = creditorRightDebt.creditor_money - oluserCredit.usable_limit;
			
			oluserCredit.transfer_used_limit += oluserCredit.usable_limit;
			
			oluserCredit.usable_limit = 0.0;
			
			oluserCredit.pledged_limit = 0.0;
		}else{
			account = creditorRightDebt.creditor_money;
			
			userCredit.transferee_limit += creditorRightDebt.creditor_money;
			userCredit.transferee_used_limit += creditorRightDebt.creditor_money;
			userCredit.usable_limit += creditorRightDebt.creditor_money;
			//增加可质押金额
			userCredit.pledged_limit += creditorRightDebt.creditor_money;
			
			
			oluserCredit.usable_limit -= creditorRightDebt.creditor_money;
			
			//减少原授信的可质押额度
			oluserCredit.pledged_limit -= creditorRightDebt.creditor_money;
			
			oluserCredit.transfer_used_limit += creditorRightDebt.creditor_money;
					
			creditorRightDebt.rest_debt_money = 0.0;
		}
		
		boolean saveCredit = save(userCredit);
		if (!saveCredit) {
			LoggerUtil.error(true, "更新应付账款债权人授信额度异常");
			result.code = -1;
			result.msg = "更新应付账款债权授信额度异常";
			return result;
		}
		saveCredit = save(oluserCredit);
		if (!saveCredit) {
			LoggerUtil.error(true, "更新当前申请人授信额度异常");
			result.code = -1;
			result.msg = "更新当前申请人授信额度异常";
			return result;
		}
		boolean save = creditorRightDebtService.updateCreditor(creditorRightDebt);
		if (!save) {
			LoggerUtil.error(false, "债权剩余金额更新异常");
			result.code = -1;
			result.msg = "债权剩余金额更新异常";
			return result;
		}
		
		// 业务流水号
		String service_order = OrderNoUtil.getNormalOrderNo(
				ServiceType.TICKET_TRANSFEREE, "");
		t_company_info_side company_info_side = companyInfoSideService.findByUserId(creditorRightDebt.company_id);
		if(company_info_side == null ){
			result.code = -1;
			result.msg = "查询不到企业信息";
			LoggerUtil.error(true, "查询不到企业信息");
			return result;
		}
		// 添加债权人额度申请明细表t_user_credit_detail
		t_user_credit_detail amountDetail = new t_user_credit_detail(
				new Date(), company_info_side.user_id, company_info_side.full_name, userCredit.credit_limit_total,
				userCredit.credit_granting_code,oluserCredit.start_time,
				oluserCredit.end_time, userCredit.lender_id,
				oluserCredit.lender_name, 0, 0, account, 0, 0,
				account, service_order,
				ServiceType.CREDIT_ACCOUNT.value, userCredit.parent_id, 0);
		boolean saveDetail = userCreditDetailService.save(amountDetail);
		if (!saveDetail) {
			result.code = -1;
			result.msg = "添加债权人额度申请明细表出现异常";
			LoggerUtil.error(true, "添加债权人额度申请明细表出现异常");
			return result;
		}
		
		// 业务流水号
		service_order = OrderNoUtil.getNormalOrderNo(
				ServiceType.TICKET_TRANSFEREE, "");
		
		// 添加申请人额度申请明细表t_user_credit_detail
		
		t_user_credit_detail detail = new t_user_credit_detail(
				new Date(), oluserCredit.user_id, oluserCredit.user_name, oluserCredit.credit_limit_total,
				oluserCredit.credit_granting_code,oluserCredit.start_time,
				oluserCredit.end_time, userCredit.lender_id,
				oluserCredit.lender_name, 0, account, 0, 0, 0,
				-account, service_order,
				ServiceType.DEBT_ACCOUNT.value, oluserCredit.id, 0);
		saveDetail = userCreditDetailService.save(detail);
		if (!saveDetail) {
			result.code = -1;
			result.msg = "添加申请人额度申请明细表出现异常";
			LoggerUtil.error(true, "添加申请人额度申请明细表出现异常");
			return result;
		}
		
		//通知应付账款债权人
		Map<String, Object> param = new HashMap<String, Object>();
		param.put("user_name", creditorRightDebt.creditor_name);
		param.put("debt_name", oluserCredit.user_name);
		param.put("account", account);
		noticeService.sendSysNotice(creditorRightDebt.company_id,
				NoticeScene.ASSOCIATED_CREDIT, param);
		
		result.code = 1;
		result.msg = "更新应付账款债权授信额度成功";
		return result;

	}*/

	/**
	 *	保存对象的同时将其返回
	 * @param userCreditSave 新申请的授信
	 * @return
	 * @author liangqiongfeng
	 *@version 2018-4-12 
	 */
	public t_user_credit saveT(t_user_credit userCredit) {
		// TODO Auto-generated method stub
		return userCreditDao.saveT(userCredit);
	}

	/**
	 *
	 * @param creditorRightDebt 账款
	 * @param company_id 申请人id
	 * @param receive_company_id 放款人id
	 * @return
	 * @author liangqiongfeng
	 *@version 2018-4-14 
	 */
	public ResultInfo toApply(t_creditor_right_debt creditorRightDebt,
			long company_id, long receive_company_id) {

		ResultInfo result = new ResultInfo();
		
		t_user_credit oluserCredit = findByUserId(company_id, receive_company_id);
		if(oluserCredit == null || oluserCredit.credit_limit_total <= 0){
			LoggerUtil.error(false, "获取不到授信信息");
			result.code = -1;
			result.msg = "获取不到授信信息";
			return result;
		}
		
		//根据授信申请绑定的应付账款，给应付账款债权人 增加受让额度
		t_user_credit userCredit = findByUserTransfer(
				creditorRightDebt.company_id, oluserCredit.id, oluserCredit.credit_granting_code);
		
		if (userCredit == null) {
			userCredit = new t_user_credit();
			userCredit.time = new Date();
			userCredit.setStatus(AuditResult.TRANSFER);
			userCredit.user_id = creditorRightDebt.company_id;
			userCredit.user_name = creditorRightDebt.creditor_name;
			userCredit.credit_granting_code =getGrantingCcode(oluserCredit.credit_granting_code);
			userCredit.start_time = oluserCredit.start_time;
			userCredit.end_time = oluserCredit.end_time;
			userCredit.financing_confine_limit = oluserCredit.financing_confine_limit;
			userCredit.bond_percent = oluserCredit.bond_percent;
			userCredit.custodian_fee = oluserCredit.custodian_fee;
			userCredit.flow_limit = oluserCredit.flow_limit;
			userCredit.parent_id = oluserCredit.id;
			userCredit.lender_id = oluserCredit.lender_id;
			userCredit.lender_name = oluserCredit.lender_name;
			
		}
		//如果应付账款已经进行过转开，不允许绑定授信申请
		if(creditorRightDebt.creditor_money != creditorRightDebt.rest_debt_money ){
			LoggerUtil.error(false, "当前账款信息不可绑定授信申请");
			result.code = -1;
			result.msg = "当前账款信息不可绑定授信申请";
			return result;
		}
		
		double account = 0.0;
		
		//如果应付账款额度大于上一级可用授信额度
		if(creditorRightDebt.creditor_money >= oluserCredit.usable_limit){
			userCredit.transferee_limit += oluserCredit.usable_limit;
			userCredit.transferee_used_limit += oluserCredit.usable_limit;
			userCredit.usable_limit += oluserCredit.usable_limit;
			
			//增加可质押金额
			userCredit.pledged_limit += oluserCredit.usable_limit;
			
			//TODO
			account = oluserCredit.usable_limit;
			
			creditorRightDebt.rest_debt_money = creditorRightDebt.creditor_money - oluserCredit.usable_limit;
			
			oluserCredit.transfer_used_limit += oluserCredit.usable_limit;
			
			oluserCredit.usable_limit = 0.0;
			
			oluserCredit.pledged_limit = 0.0;
		}else{
			account = creditorRightDebt.creditor_money;
			
			userCredit.transferee_limit += creditorRightDebt.creditor_money;
			userCredit.transferee_used_limit += creditorRightDebt.creditor_money;
			userCredit.usable_limit += creditorRightDebt.creditor_money;
			//增加可质押金额
			userCredit.pledged_limit += creditorRightDebt.creditor_money;
			
			
			oluserCredit.usable_limit -= creditorRightDebt.creditor_money;
			
			//减少原授信的可质押额度
			oluserCredit.pledged_limit -= creditorRightDebt.creditor_money;
			
			oluserCredit.transfer_used_limit += creditorRightDebt.creditor_money;
					
			creditorRightDebt.rest_debt_money = 0.0;
		}
		
		boolean saveCredit = save(userCredit);
		if (!saveCredit) {
			LoggerUtil.error(true, "更新应付账款债权人授信额度异常");
			result.code = -1;
			result.msg = "更新应付账款债权授信额度异常";
			return result;
		}
		saveCredit = save(oluserCredit);
		if (!saveCredit) {
			LoggerUtil.error(true, "更新当前申请人授信额度异常");
			result.code = -1;
			result.msg = "更新当前申请人授信额度异常";
			return result;
		}
		boolean save = creditorRightDebtService.updateCreditor(creditorRightDebt);
		if (!save) {
			LoggerUtil.error(false, "债权剩余金额更新异常");
			result.code = -1;
			result.msg = "债权剩余金额更新异常";
			return result;
		}
		
		// 业务流水号
		String service_order = OrderNoUtil.getNormalOrderNo(
				ServiceType.TICKET_TRANSFEREE, "");
		t_company_info_side company_info_side = companyInfoSideService.findByUserId(creditorRightDebt.company_id);
		if(company_info_side == null ){
			result.code = -1;
			result.msg = "查询不到企业信息";
			return result;
		}
		// 添加债权人额度申请明细表t_user_credit_detail
		t_user_credit_detail amountDetail = new t_user_credit_detail(
				new Date(), company_info_side.user_id, company_info_side.full_name, userCredit.credit_limit_total,
				userCredit.credit_granting_code,oluserCredit.start_time,
				oluserCredit.end_time, userCredit.lender_id,
				oluserCredit.lender_name, 0, 0, account, 0, 0,
				account, service_order,
				ServiceType.CREDIT_ACCOUNT.value, userCredit.parent_id, 0);
		boolean saveDetail = userCreditDetailService.save(amountDetail);
		if (!saveDetail) {
			result.code = -1;
			result.msg = "添加债权人额度申请明细表出现异常";
			LoggerUtil.error(true, "添加债权人额度申请明细表出现异常");
			return result;
		}
		
		// 业务流水号
		service_order = OrderNoUtil.getNormalOrderNo(
				ServiceType.TICKET_TRANSFEREE, "");
		
		// 添加申请人额度申请明细表t_user_credit_detail
		
		t_user_credit_detail detail = new t_user_credit_detail(
				new Date(), oluserCredit.user_id, oluserCredit.user_name, oluserCredit.credit_limit_total,
				oluserCredit.credit_granting_code,oluserCredit.start_time,
				oluserCredit.end_time, userCredit.lender_id,
				oluserCredit.lender_name, 0, account, 0, 0, 0,
				-account, service_order,
				ServiceType.DEBT_ACCOUNT.value, oluserCredit.id, 0);
		saveDetail = userCreditDetailService.save(detail);
		if (!saveDetail) {
			result.code = -1;
			result.msg = "添加申请人额度申请明细表出现异常";
			LoggerUtil.error(true, "添加申请人额度申请明细表出现异常");
			return result;
		}
		
		//通知应付账款债权人
		Map<String, Object> param = new HashMap<String, Object>();
		param.put("user_name", creditorRightDebt.creditor_name);
		param.put("debt_name", oluserCredit.user_name);
		param.put("account", account);
		noticeService.sendSysNotice(creditorRightDebt.company_id,
				NoticeScene.ASSOCIATED_CREDIT, param);
		
		result.code = 1;
		result.msg = "更新应付账款债权授信额度成功";
		return result;
	}

	/**
	 * 更新授信
	 * @param userCredit
	 * @return
	 * @author liangqiongfeng
	 *@version 2018-4-17 
	 */
	public boolean updateBySQL(t_user_credit userCredit) {
		StringBuffer sql = new StringBuffer("UPDATE `t_user_credit` SET  `credit_limit_total`=:credit_limit_total,  `start_time`=:start_time,  `usable_limit`=:usable_limit, `pledged_limit`= :pledged_limit WHERE id = :id");
		Map<String,Object> condistion = new HashMap<String, Object>();
		condistion.put("credit_limit_total", userCredit.credit_limit_total);
		condistion.put("start_time", userCredit.start_time);
		condistion.put("usable_limit", userCredit.usable_limit);
		condistion.put("pledged_limit", userCredit.pledged_limit);
		condistion.put("id", userCredit.id);
		return userCreditDao.updateBySQL(sql.toString(), condistion) > 0 ? true : false;
	}

	

	
	
}
